{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Using `mayavi.mlab`: going deeper\n",
    "\n",
    "**Prabhu Ramachandran**\n",
    "\n",
    "**Department of Aerospace Engineering, IIT Bombay**\n",
    "\n",
    "<br/>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Outline\n",
    "\n",
    "- Getting started with `mlab`\n",
    "- Using `mlab`\n",
    "   - The basics\n",
    "   - Animation\n",
    "- **Going deeper**  $\\Longleftarrow$\n",
    "   - The pipeline\n",
    "   - Data sources\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "%gui qt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from mayavi import mlab"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Recap\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def lorenz(x, y, z, s=10.,r=28.,\n",
    "           b=8./3.):\n",
    "    u = s*(y-x)\n",
    "    v = r*x -y - x*z\n",
    "    w = x*y - b*z\n",
    "    return u, v, w\n",
    "\n",
    "x, y, z = np.mgrid[-50:50:20j,-50:50:20j,\n",
    "                   -10:60:20j]\n",
    "u, v, w = lorenz(x, y, z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlab.quiver3d(\n",
    "    x, y, z, u, v, w,\n",
    "    scale_factor=0.01,\n",
    "    mask_points=5\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Viewing the pipeline\n",
    "\n",
    "* On scene toolbar, click on Mayavi icon\n",
    "\n",
    "* Or:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.show_pipeline()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Looking inside\n",
    "\n",
    "<center>\n",
    "<img src=\"MEDIA/m2/mlab/mlab_pipeline1.png\"/>\n",
    "</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## The pipeline\n",
    "\n",
    "<center>\n",
    "<img src=\"MEDIA/m2/quiver_pipeline.png\"/>\n",
    "</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "<center>\n",
    "<img src=\"MEDIA/m2/m2_big_picture.png\" width=\"70%\" height=\"70%\"/>\n",
    "</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Changing the pipeline\n",
    "\n",
    "### On UI\n",
    "\n",
    "* Right click on node\n",
    "* Mayavi app: also in app menus\n",
    "* drag drop\n",
    "\n",
    "### Script\n",
    "\n",
    "* Or use `mlab.pipeline`\n",
    "* Example: `mlab.pipeline.outline()`\n",
    "* We look at more useful methods later\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Another example pipeline\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.random.random((4, 4))\n",
    "mlab.clf()\n",
    "mlab.surf(a)\n",
    "mlab.show_pipeline()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center>\n",
    "<img src=\"MEDIA/m2/mlab/simple_pipeline_demo.png\" width=\"40%\" height=\"30%\" />\n",
    "</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Using `mlab.pipeline`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.array2d_source(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "warp = mlab.pipeline.warp_scalar(src)\n",
    "normals = mlab.pipeline.poly_data_normals(warp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "surf = mlab.pipeline.surface(normals)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Does exactly what `mlab.surf(a)` does!\n",
    "* Lower-level but full control\n",
    "* More options\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Exercise\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "x, y, z = np.ogrid[-5:5:64j, -5:5:64j, -5:5:64j]\n",
    "o = mlab.contour3d(x*x*0.5 + y*y + z*z*2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Modify contour parameters\n",
    "\n",
    "* Hide the existing contours\n",
    "\n",
    "* Add a scalar cut plane\n",
    "\n",
    "* Do these with the UI\n",
    "\n",
    "* Do them with scripting (also use `mlab.pipeline`)\n",
    "\n",
    "* Remove the scalar cut plane\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Some tips: try these\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x, y, z = np.ogrid[-5:5:64j, -5:5:64j, -5:5:64j]\n",
    "o = mlab.contour3d(x*x*0.5 + y*y + z*z*2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "o.visible = False # or True\n",
    "p = o.parent\n",
    "print(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(p.parent)\n",
    "p.children"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "o.remove()\n",
    "mlab.pipeline.grid_plane(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## A useful trick\n",
    "\n",
    "- If you want to quickly configure parameters for a particular object\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "p.edit_traits()\n",
    "# Will pop up a UI for `p` alone!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Recap\n",
    "\n",
    "* `obj.visible`\n",
    "* `obj.parent`\n",
    "* `obj.children` : modules have none\n",
    "\n",
    "* `obj.remove()`\n",
    "* `mlab.pipeline`  lets us do more\n",
    "* `obj.edit_traits()`: UI for `obj`\n",
    "\n",
    "* Right-click-menu equivalents are in `mlab.pipeline`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### So how do you make a fancier script?\n",
    "\n",
    "Use script recording\n",
    "\n",
    "**Demo**\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Exercise\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.test_flow()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Add a Vector Cut Plane\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "mlab.test_quiver3d()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Hide vectors, add a Vector Cut Plane\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Surprised?\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## So what is the problem?\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Points?\n",
    "\n",
    "<center>\n",
    "<img src=\"MEDIA/m2/datasets/points.png\"/>\n",
    "</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Curve?\n",
    "\n",
    "<center>\n",
    "<img src=\"MEDIA/m2/datasets/wireframe.png\"/>\n",
    "</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Surface?\n",
    "\n",
    "<center>\n",
    "<img src=\"MEDIA/m2/datasets/surface.png\"/>\n",
    "</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Interior of sphere?\n",
    "\n",
    "<center>\n",
    "<img src=\"MEDIA/m2/datasets/surface.png\"/>\n",
    "</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "\n",
    "## What is the intersection of a plane with each of these?\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Going deeper\n",
    "\n",
    "### Data sources\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Datasets\n",
    "Quiver v/s Flow\n",
    "\n",
    "<table>\n",
    "<tr>\n",
    "<td><img src=\"MEDIA/m2/quiver_pipeline.png\" width=\"100%\"/></td>\n",
    "<td><img src=\"MEDIA/m2/flow_pipeline.png\" width=\"100%\"/></td>\n",
    "</tr>\n",
    "</table>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Data sources and Datasets\n",
    "\n",
    "* Intimately connected to VTK \"datasets\"\n",
    "\n",
    "* Datasets\n",
    "\n",
    "   * Structure: Geometry and topology\n",
    "   * Attribute data associated with the structure\n",
    "\n",
    "\n",
    "* Example: Temperature distribution in the room\n",
    "* Example: Stress distribution on chair\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Datasets in mlab\n",
    "\n",
    "* `mlab`  provides a few data sources\n",
    "\n",
    "* Not the most general currently\n",
    "\n",
    "* Three broad categories:\n",
    "\n",
    "   1. Unconnected sources\n",
    "   1. Implicitly connected sources\n",
    "   1. Explicitly connected sources\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Unconnected sources\n",
    "\n",
    "| `scalar_scatter` | `vector_scatter` |\n",
    "| ---------------- | ---------------- |\n",
    "| <img src=\"MEDIA/m2/mlab/points3d_ex.png\"/> | <img src=\"MEDIA/m2/mlab/quiver3d_ex.png\"/> |\n",
    "|`PolyData`      | `PolyData`    |\n",
    "|`mlab.points3d`   | `mlab.quiver3d` |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Implicitly-connected sources\n",
    "\n",
    "| `scalar_field`    |   `vector_field`  |\n",
    "| ----------------- | ---------------   |\n",
    "| <img src=\"MEDIA/m2/mlab/contour3d.png\" height=\"75%\" width=\"100%\"/> | <img src=\"MEDIA/m2/mlab/flow_ex.png\" width=\"75%\" height=\"60%\" /> |\n",
    "| `ImageData`       | `ImageData`     |\n",
    "| `mlab.contour3d`  | `mlab.flow`     |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Implicitly-connected sources\n",
    "\n",
    "`array2d_source`\n",
    "\n",
    "<img src=\"MEDIA/m2/mlab/imshow_ex.png\" width=\"50%\" height=\"50%\"/>\n",
    "\n",
    "`ImageData`\n",
    "\n",
    "`mlab.imshow`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Explicitly-connected sources\n",
    "| `line_source`  | `triangular_mesh_source` |\n",
    "| -------------- | ---------------------- |\n",
    "| <img src=\"MEDIA/m2/mlab/plot3d_ex.png\"/> |  <img src=\"MEDIA/m2/mlab/triangular_mesh_ex.png\"/> |\n",
    "|`PolyData`      | `PolyData`    |\n",
    "|`mlab.plot3d`   | `mlab.triangular_mesh` |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Summary\n",
    "\n",
    "* Unconnected: points in space\n",
    "\n",
    "* Connected: represent surface or volume\n",
    "\n",
    "* Attributes associated with structure are rendered\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Exercise (Homework?)\n",
    "\n",
    "* Run all the `mlab.test_*`  functions\n",
    "\n",
    "* Read the source for each\n",
    "\n",
    "* Inspect the pipeline for each example\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Recap\n",
    "\n",
    "* `mlab`  gets you started\n",
    "* Pipeline and data flow\n",
    "* Datasets are important!\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## `mlab`  and Mayavi?\n",
    "\n",
    "* `mlab` : thin layer over the Mayavi OO API\n",
    "\n",
    "* `mlab`  commands return mayavi objects\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Exercise\n",
    "\n",
    "* Visualize the following vector field\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from numpy import mgrid, sin, cos, pi\n",
    "s = slice(0, 1, 20j)\n",
    "x, y, z = mgrid[s,s,s]\n",
    "\n",
    "u = sin(pi*x) * cos(pi*z)\n",
    "v = -2*sin(pi*y) * cos(2*pi*z)\n",
    "w = cos(pi*x)*sin(pi*z) + cos(pi*y)*sin(2*pi*z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Hints / Solution\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "src = mlab.pipeline.vector_field(\n",
    "    x, y, z, u, v, w\n",
    ")\n",
    "# ------------------------------------\n",
    "mlab.pipeline.vectors(\n",
    "    src, mask_points=20, scale_factor=0.5\n",
    ")\n",
    "# ------------------------------------\n",
    "mlab.pipeline.vector_cut_plane(\n",
    "    src, mask_points=2, scale_factor=0.5\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Hints / Solution\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mag = mlab.pipeline.extract_vector_norm(src)\n",
    "mlab.pipeline.iso_surface(\n",
    "    mag, contours=[1.9, 0.5]\n",
    ")\n",
    "# ------------------------------------\n",
    "flow = mlab.flow(\n",
    "    x, y, z, u, v, w, seed_scale=1,\n",
    "    seed_resolution=5,\n",
    "    integration_direction='both'\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Exercise: play with your own data\n",
    "\n",
    "Explore your own data with `mlab`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Exercise (if you don't have your own data)\n",
    "\n",
    "1. Start with flow for the Lorenz system\n",
    "1. Now extract the vector norm (use a filter)\n",
    "1. Plot iso-contours of this\n",
    "1. Figure out how to do this from the UI and `mlab.pipeline`\n"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  },
  "livereveal": {
   "controls": true,
   "help": true,
   "scroll": true,
   "slideNumber": true,
   "transition": "none"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
